#!/usr/bin/python
# -*- coding: utf-8 -*-
#Under the terms of the General Public License v.3
#For more information see LICENSE.txt

import pygame
from pygame.sprite import Sprite
import infoimages
import thread


class Element(Sprite):

	def __init__(self, obj, posX, posY):
		self.image = InfoImages.getImage(obj)
		self.rect = self.image.get_rect()
		self.setPosXY(posX, posY)

	def getCenter(self):
		x = (self.getWidth() / 2) + self.getPosX()
		y = (self.getHeight() / 2) + self.getPosY()
		return (x, y)

	def getPosX(self):
		return self.posX
	
	def setPosX(self, posX):
		self.posX = posX

	def getPosY(self):
		return self.posY
	
	def setPosY(self, posY):
		self.posY = posY

	def setPosXY(self, posX, posY):
		self.posX = posX
		self.posY = posY

	def getPosXY(self):
		return (self.getPosX(), self.getPosY())

	def getWidth(self):
		return self.rect.width

	def getHeight(self):
		return self.rect.height

	def getWidthHeigth(self):
		return (self.width, self.heigth)

	def update(self):
		pass
	
	def paint(self, surface):
		surface.blit(self.image, self.getPosXY())
	"""
	def collides(self, element):
		up = self.posY
		down = self.posY + self.height
		left = self.posX
		right = self.posX + self.width
	
		if ( up <= (element.getPosY() + element.getHeight()) ):
			return True
		if ( down >= element.getPosY() ):
			return True
		if ( left <= (element.getPosX() + element.getWidth()) ):
			return True
		if ( right >= element.getPosX() ):
			return True

		return False
	"""
# Hasta que leo lo explique :P
	def collides(self, element):
		reldistX = abs(self.posX - element.posX)
		reldistY = abs(self.posY - element.posY)
		relYmax = abs(self.heigth/2 + element.heigth/2)
		relXmax = abs(self.width/2 + element.width/2)
		if relXmax < reldistX and relYmax < reldistY:
			return True
		return False


class AccessPoint (Element):

	def __init__(self, image, posX, posY, power):
		Element.__init__(self, image, posX, posY)
		self.initConstants()
		self.image.set_colorkey(self.TRANSPARENT_COLOR)
		self.waveRadius = self.MIN_RADIUS
		self.power = power
		self.life = True
		self.initSound()
		self.turnOn()

	def initConstants(self):
		self.TRANSPARENT_COLOR = (0xFF, 0xFF, 0xFF)
		self.MIN_RADIUS = 10
		self.WAVE_COLOR = (0, 0x7F, 0xFF)
		self.WAVE_WIDTH = 1
		self.WAVE_DELAY_MS = 100
		self.SOUND_PATH = "data/sfx/"
		self.SOUND = self.SOUND_PATH + "ap_sound.wav"
		self.SOUND_VOLUME = 0.6

	def initSound(self):
		self.sound = pygame.mixer.Sound(self.SOUND)
		self.sound.set_volume(self.SOUND_VOLUME)

	def isAlive(self):
		return self.life

	def setLife(self, life):
		self.life = life

	def getPower(self):
		return self.power

	def setPower(self, power):
		self.power = power

	def turnOff(self):
		self.setLife(False)

	def turnOn(self):
		self.setLife(True)

	def playSound(self):
		self.sound.play()

	def paint(self, surface):
		thread.start_new_thread(self.paintThread, (surface, 0))

	def paintThread(self, surface, nothing):
		while self.life:
			self.waveRadius %= self.power
			self.waveRadius += self.MIN_RADIUS

			if (self.waveRadius == self.MIN_RADIUS):
				self.playSound()

			Element.paint(self, surface)
			pygame.draw.circle(surface, self.WAVE_COLOR, self.getCenter(), self.waveRadius, self.WAVE_WIDTH)
			pygame.time.delay(self.WAVE_DELAY_MS)
			pygame.display.flip()

class Obstacle (Element):
    pass

class Piedra (Obstacle):
    pass



class Player (Element):

	def __init__(self, image, posX, posY):
		Element.__init__(self, imagePath, posX, posY)
		self.map = map
		self.image = pygame.image.load(imagePath).convert_alpha()
		self.rect = self.image.get_rect()
		self.rect.move_ip(120, 150)
		self.pointControl_x = 78
		self.pointControl_y = 58
		
	def setSpeedX(self, speedX):
		self.speedX = speedX

	def setspeedY(self, speedY):
		self.speedY = speedY

	def getSpeedX(self):
		return self.speedX

	def getSpeedY(self):
		return self.speedY

	def updatePosition(self):
		self.updatePosition(self, self.posX + self.speedX, self.posY + self.speedY)

	def updatePosition(self, newPosX, newPosY):
		self.posX = newPosX
		self.posY = newPosY
	"""
	def checkBoundColision(self, posX, posY):
		pass
	"""
class Robot(Player):

	def __init__(self, image, posX, posY):
		Player.__init__(self, image, posX, posY)
		self.movement = 5
		self.move_sound = pygame.mixer.Sound("data/sfx/robot_move.wav")
		self.move_sound.set_volume(0.75)
		
	def playMoveSound(self):
		self.move_sound.play()
		
	def stopMoveSound(self):
		self.move_sound.stop()
		
	def update(self):
		teclas = pygame.key.get_pressed()
		if teclas[K_LEFT]:
			self.playMoveSound()
			if self.rect.x > 0:
				self.rect.x -= self.movement
		if teclas[K_RIGHT]:
			self.playMoveSound()
			if self.rect.x < 593:
				self.rect.x += self.movement
		if teclas[K_UP]:
			self.playMoveSound()
			if self.rect.y > 0:
				self.rect.y -= self.movement
		if teclas[K_DOWN]:
			self.playMoveSound()
			if self.rect.y < 433:
				self.rect.y += self.movement
				
	def slowDown(self, slowPower):
		self.movement -= slowPower
		
	def powerOff(self):
		self.movement = 0
		
	def goFaster(self, fastPower):
		self.movement += fastPower


class Human (Player):

	def __init__(self, image, posX, posY, level, apList):
		self.initConstants(level)
		self.isAlive(True)
		self.setLevel(level)
		self.apList = apList
		Player.__init__(self, image, posX, posY)
		thread.start_new_thread(self.start, (0, 0))

	def initConstants(self, level):
		self.PAINT_DELAY_MS = 50
		self.TIME_TO_KILL_AP = level
		self.TIME_POWER_RATIO_AP = 0.01
		self.TIME_TO_SLEEP = 30
		self.NEAR_DISTANCE = 15

	def start(self, nothing0, nothing1):
		for ap in self.apList:
			self.setAp(ap)
			self.killAp()

	def paint(self, screen):
		thread.start_new_thread(self.paintThread, (screen, 0))
	
	def paintThread(self, screen, nothing):
		while self.isAlive():
			pygame.time.delay(self.PAINT_DELAY_MS)
			screen.blit(self.image, (self.getPosX(), self.getPosY()))
			pygame.display.flip()
	
	def getLevel(self):
		return self.level

	def setLevel(self, level):
		self.level = level

	def isAlive(self):
		return self.alive

	def isAlive(self, alive):
		self.alive = alive

	def killHuman(self):
		self.isAlive(False)

	def killAp(self):
		xSign = int((self.getAp().getPosX() - self.getPosX()) / abs(self.getAp().getPosX() - self.getPosX()))
		ySign = int((self.getAp().getPosY() - self.getPosY()) / abs(self.getAp().getPosY() - self.getPosY()))
		xDist = abs(self.getAp().getPosX() - self.getPosX())
		yDist = abs(self.getAp().getPosY() - self.getPosY())
		self.setSpeedX(self.getLevel() * xSign)
		self.setSpeedY(yDelta = int(abs(xDelta) * ySign * yDist / xDist))

		while (not self.isNearAp()):
			self.updatePosition()
			time.sleep(self.TIME_TO_SLEEP)

		time.sleep(sleep.TIME_TO_KILL_AP + self.TIME_POWER_RATIO_AP * self.getAp().getPower())
		self.getAp().turnOff()

	def isNearAp(self):
		xDist = abs(self.getAp().getPosX() - self.getPosX())
		yDist = abs(self.getAp().getPosY() - self.getPosY())

		if ((xDist <= self.NEAR_DISTANCE) and (yDist <= self.NEAR_DISTANCE)):
			return True
		else:
			return False
	
	def getAp(self):
		return self.ap

	def setAp(self, ap):
		self.ap = ap


class Item(Element):
	
	def __init__(self, image, posX, posY):
		Element.__init__(self, image, posX, posY)
		self.initConstants()
		self.isTaken(False)
		self.image.set_colorkey(self.TRANSPARENT_COLOR)

	def initConstants(self):
		self.TRANSPARENT_COLOR = (0xFF, 0xFF, 0xFF)
		self.PAINT_DELAY_MS = 50

	def isTaken(self):
		return self.taken

	def isTaken(self, taken):
		self.taken = taken

	def paint(self, screen):
		thread.start_new_thread(self.paintThread, (screen, 0))

	def paintThread(self, screen, nothing):
		while (not self.isTaken()):
			Element.paint(self, screen)
			pygame.time.delay(self.PAINT_DELAY_MS)
	
	def action(self):
		pass


class ItemBad(Item):
	
	def __init__(self, image, posX, posY):
		Item.__init__(self, image, posX, posY)

	def action(self, victim):
		self.doDamage(victim)


class ItemBadApTurnOff(ItemBad):

	def __init__(self, image, posX, posY):
		ItemBad.__init__(self, image, posX, posY)

	def doDamage(self, ap):
		ap.turnOff()

class ItemBadSlower(ItemBad):

	def __init__(self, image, posX, posY, slowPower):
		self.slowPower = slowPower
		ItemBad.__init__(self, image, posX, posY)

	def doDamage(self, robot):
		robot.slowDown(self.slowPower)

class ItemBadStopper(ItemBad):

	def __init__(self, image, posX, posY, stopPower):
		self.stopPower = stopPower
		ItemBad.__init__(self, image, posX, posY)

	def doDamage(self, robot):
		robot.powerOff()


class ItemGood(Item):

	def __init__(self, image, posX, posY):
		Item.__init__(self, image, posX, posY)

	def action(self, victim):
		self.doBonus(victim)

class ItemGoodApTurnOn(ItemGood):

	def __init__(self, image, posX, posY):
		ItemGood.__init__(self, image, posX, posY)

	def doBonus(self, ap):
		ap.turnOn()

class ItemGoodEvolutive(ItemGood):

	def __init__(self, image, posX, posY, id):
		self.id = id
		ItemGood.__init__(self, image, posX, posY)

	def doBonus(self, robot):
		robot.evolution(self.id)

class ItemGoodFaster(ItemGood):

	def __init__(self, image, posX, posY, fastPower):
		self.fastPower = fastPower
		ItemGood.__init__(self, image, posX, posY)

	def doBonus(self, robot):
		robot.goFaster(self.fastPower)

class ItemGoodKillHuman(ItemGood):

	def __init__(self, image, posX, posY):
		ItemGood.__init__(self, image, posX, posY)

	def doBonus(self, human):
		human.killHuman()

class ItemGoodMemory(ItemGood):

	def __init__(self, image, posX, posY, memoryPower):
		self.memoryPower = memoryPower
		ItemGood.__init__(self, image, posX, posY)

	def doBonus(self, robot):
		robot.rememberMore(self.memoryPower)


